#ifndef PREANNOSTRUCTURE_H
#define PREANNOSTRUCTURE_H

#include <QtGui>
#include <QApplication>
#include <QTableWidgetItem>

#include "ModelSwap.h"


static inline void OpenDe( QUrl loc )
{
    #if defined Q_WS_MAC
    QProcess *m = new QProcess();
    QStringList macs;
    macs << loc.toString();  /* oeffnet der default browser */
    m->startDetached(QString("open") , macs );
    ///////std::cout << "OpenDesktop [" << qPrintable(macs.join(" ")) << "]" << std::endl;
    return;
    #endif 
    
#if defined Q_WS_WIN
    
    QString fullFileName = loc.toString();
    
    if (fullFileName.startsWith("http://", Qt::CaseInsensitive) ||
        fullFileName.startsWith("https://", Qt::CaseInsensitive) ||
        fullFileName.startsWith("ftp://", Qt::CaseInsensitive) ||
        fullFileName.startsWith("news://", Qt::CaseInsensitive) ||
        fullFileName.startsWith("mailto:", Qt::CaseInsensitive) ||
        fullFileName.startsWith("webdav://", Qt::CaseInsensitive)  )
       { 
         /* all ok */
       } else {
         fullFileName.prepend("file:///");  
       }
    bool wr = QDesktopServices::openUrl(QUrl(fullFileName));
    if (!wr) {
    QMessageBox::warning(0, qApp->tr("Error"),qApp->tr("Window Unable to open action file or dir  %1").arg(loc.toString()));
    }
return;
#endif
    
    /* linux */

     bool r = QDesktopServices::openUrl(loc);
    if (!r) {
    QMessageBox::warning(0, qApp->tr("Error"),qApp->tr("Linux Unable to open action file or dir  %1").arg(loc.toString()));
    }
    
}






class CustomDelegate : public QItemDelegate
{
public:
    CustomDelegate(QObject *parent = 0) : QItemDelegate(parent) {}
    ~CustomDelegate() {}
    void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
			   QStyleOptionViewItem opt0 = setOptions(index,option);
			
			   if (option.state & QStyle::State_Selected) {
						opt0.decorationPosition  = QStyleOptionViewItem::Top;
					  QItemDelegate::paint(painter,opt0,index);
				 } else {
			  QStyleOptionViewItem opt = setOptions(index,option);
				opt.textElideMode = Qt::ElideMiddle;
				opt.decorationPosition  = QStyleOptionViewItem::Bottom;
			  QItemDelegate::paint(painter,opt,index);
				 }
    }
};








class CalendarItem : public QTableWidgetItem
{
public:
    CalendarItem( const QDate d );
    CalendarItem(const QString &text);
    inline void Tipe( QString txt ) {
     QTableWidgetItem::setToolTip(txt.left(3)+"..."); 
		}			
private:
    QDate day;
};


//
class DayCell
{
//
public:
 enum { MAGICNUMBER = 0x48611928, VERSION = 5 };
 DayCell();
 QIcon createColorToolButtonIcon( int setmodus );
 DayCell operator=( const DayCell d );
 /*bool DayCell::operator==( const DayCell &d ) const;*/
 void Register( int tr , int td , const QDate d ,  int gyear , int mod = 0 );
 CalendarItem *on_Table();
 void Fill_Html_Cell( QTextTableCell hcell , bool outday = false );
 bool isValid();
 inline operator QVariant() const {
    return QVariant::fromValue(*this);
  }
 inline QSize sizeHint() const  {
   return QSize(12,12);
 }
 QPixmap NoteIcon();
 int fromUday();   /* ID to save not free day  summ of day from 1.1.1970 to date */
 QColor BG( int setmodus );  /* background color from modus */
 QColor FC( int setmodus ); /* foreground from modus */
 QString text(); /* day as string */
 int day();  /* day nummer */
 int year(); 
 //////bool outsider;
 QString alternate_text;
 
  /* vars permanent */
    int td_line;  /* on model go to cell / cools  x*/
    int tr_line;  /* on model go to row */
    int modus; /* reservation modus    0= libero / 1= prenotato / 2= prenotato provvisorio / 3= riservato / 10 = chiuso / */
    int anno;
    QDate dax;
    QByteArray data;  /* reserve! image or so ... */
    QStringList note; 
 
};

Q_DECLARE_METATYPE(DayCell);

inline QDebug operator<<(QDebug debug, const DayCell& tline)
{
	debug.nospace() << "DayCell()" 
		    << tline.td_line << "," 
        << tline.tr_line << "," 
        << tline.modus << ",date()" 
        << tline.dax << "," 
        << tline.anno << ","
        << tline.data << ","    
        << tline.note << ")";
	return debug.space();
}

QDataStream& operator>>(QDataStream& in, DayCell& udoc);
QDataStream& operator<<(QDataStream& out, const DayCell& udoc);



/*

  /////  hard work ! 
class DateDelegate : public QItemDelegate
 {
     Q_OBJECT

 public:
     DateDelegate(QWidget *parent = 0) : QItemDelegate(parent) {}
     void drawBackground(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
     void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
     QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
 private slots:
 };
 
*/








class TableCalendar
{
//
public:
 enum { MAGICNUMBER = 0x42211928, VERSION = 1 };
 TableCalendar();  /* excel flat calendar */
 void InitRange( int mi ,  int max , const int user );  /* year range min , max */
 QString name_m( int m );
 void AppendMonth( int y, int m );
 void AppendYear( int y );
 QString html_year( int y );
 QPixmap image_year( int y );  /* web 20 kb ! */
 /* display */
 QList<DayCell> Take( int y  );
 QList<DayCell> Take( int y  , int line );   /* line = month - 1 */
 DayCell TakeItem( int epoca );  /* ritira un giorno preciso !*/
 QList<QDate> ram_day;  /* construct calendar flat each year on table */
 QList<DayCell> visual_day;  /* construct calendar flat each year on table */
 int LunghezzaMassimaRighe( int anno );
 inline operator QVariant() const {
    return QVariant::fromValue(*this);
 }
 inline bool isMemo( int epoche  ) 
 {
        if (MemoDay.size() < 1) {
         return false;
        }
             QMapIterator <int,DayCell> i(MemoDay);
                while (i.hasNext()) {
                     i.next();
                      if ( i.key() == epoche ) {
                        return true;
                      }
                 }
                 
   return false;
  }
	inline void appendlist( QMap<int,DayCell> income  ) 
 {
        if (income.size() < 1) {
         return;
        }
             QMapIterator <int,DayCell> i(income);
                while (i.hasNext()) {
                     i.next();
										 MemoDay.insert(i.key(),i.value());
                 }
				
  }
 
   int anno_min;
   int anno_max;
	
  inline int memo_size() { return MemoDay.size(); }
  QString Html_build();
  inline QMap<int,DayCell> Works() { return MemoDay; }
 /* save arguments on stream */
 /* day int from 1.1.1970 to day x + DayCell */
  QMap<int,DayCell> MemoDay;
   int owner;
   QString data;
   QString web;   /* image png base64 encoded */
   QDateTime lastupdate;
};

Q_DECLARE_METATYPE(TableCalendar);

/* salvare i codici delle immagini attributi case hotel ecc... */
inline QString saveCalendar( TableCalendar& xdata  )
{
	
	/////////////////xdata.Html_build(); !!!!QPixmap in theard    /* make image from calendar */
	
  QMap<int,DayCell> li = xdata.Works();
  
	QByteArray bytes;
	QBuffer buffer(&bytes);
	if (!buffer.open(QIODevice::WriteOnly)) {
		return QString();
	}
	QDataStream ds(&buffer);
	/* place header */
	ds.setVersion(QDataStream::Qt_4_2);
	ds << (quint32)TableCalendar::MAGICNUMBER;
	ds << (quint32)TableCalendar::VERSION;
	/* place header */
	ds << xdata.owner;
	ds << xdata.data;
  ds << xdata.web;
  ds << xdata.lastupdate;
  
             QApplication::setOverrideCursor(Qt::WaitCursor);
  
            QMapIterator <int,DayCell> i(li);
                while (i.hasNext()) {
                     i.next();
                     DayCell appoint = i.value();
									     if (appoint.modus > 0 ||  appoint.note.size() > 0 ) {
                        ds << appoint;
											 }
                 }
             QApplication::restoreOverrideCursor();
	buffer.close();
	return bytes.toBase64();
}



/* decoded base64 stream to put on mysql row , file or network streams */
inline TableCalendar openCalendar( const QString datastream_base64   )
{
	QByteArray xcode("");
  TableCalendar xdata;
	xcode.append(datastream_base64);
	quint32 magic, version;
	QByteArray bytes(QByteArray::fromBase64(xcode));   /* decoded base64 string to QByteArray */
	QBuffer buffer(&bytes);
	if (!buffer.open(QIODevice::ReadOnly)) {
		return xdata;
	}
  
	QDataStream ds(&buffer);
	/* place header */
	ds.setVersion(QDataStream::Qt_4_2);
	ds >> magic;
	if ( (quint32)TableCalendar::MAGICNUMBER != magic ) {
    qDebug() << "######## MAGICNUMBER not ok  ";
		buffer.close();
		return xdata;
	}
	ds >> version;
	if ( (quint32)TableCalendar::VERSION != version ) {
		qDebug() << "######## VERSION not ok  ";
		buffer.close();
		return xdata;
	}
	/* place header */
  ds >> xdata.owner;
	ds >> xdata.data;
  ds >> xdata.web;
  ds >> xdata.lastupdate;
  //////QApplication::setOverrideCursor(Qt::WaitCursor);
    while (!ds.atEnd()) {
         DayCell appoint;
         ds >> appoint;
			   if (appoint.modus > 0 ||  appoint.note.size() > 0 ) {
         xdata.MemoDay.insert(appoint.fromUday(),appoint);
				 }
    }
   //////QApplication::restoreOverrideCursor();
	buffer.close();
	return xdata;
}








class Calendar : public QTableWidget
{
	Q_OBJECT 
	
public:
	Calendar( int user = 0 , QWidget *parent = 0 );
  void init( int user = 0);
  void contextMenuEvent ( QContextMenuEvent * e );
  bool HavingYear( int y );
  QString Export();
  void  Import( const QString dat );
  
  TableCalendar taco;
  int MaxY;
  int colonnemassimo;
  int MinY;
  int ActiveYear;
  signals:
      void Range(int,int,int);
  public slots:
  void SwapYear();
  void Riservati();
  void Notaday();
  void ExportAsFile();
  void ImportFromFile();
	void PlayYear( const int InYear);
	void ExportFileHtml();
	void ExportFileXml();
	void ExportasImage();

};



class GCalendar : public QDialog
{
    Q_OBJECT
//
public:
 GCalendar( int user = 1000 , QWidget * parent = 0 )
{
    resize(1000,350);
	  gridLayout = new QGridLayout(this);
    tableWidget = new Calendar(user,this);
    gridLayout->addWidget(tableWidget, 0, 0, 1, 1);
    hboxLayout = new QHBoxLayout();
    label = new QLabel(this);
    hboxLayout->addWidget(label);
    spinBox = new QSpinBox(this);
	  spinBox->setMinimumSize(QSize(100, 0));
    hboxLayout->addWidget(spinBox);
    spacerItem = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
    hboxLayout->addItem(spacerItem);
    pushButton = new QPushButton(this);
    hboxLayout->addWidget(pushButton);
    pushButton_2 = new QPushButton(this);
    hboxLayout->addWidget(pushButton_2);
    gridLayout->addLayout(hboxLayout, 1, 0, 1, 1);
	
		label->setText(tr("Mostra anno:"));
    pushButton->setText(tr("OK salva"));
    pushButton_2->setText(tr("Chiudi"));
		connect(tableWidget, SIGNAL(Range(int,int,int)), this, SLOT(UpdateChoise(int,int,int)));
		
		
		
 
		
		setWindowTitle(tableWidget->windowTitle());
		connect(pushButton, SIGNAL(clicked()), this, SLOT(save()));
    connect(pushButton_2, SIGNAL(clicked()), this, SLOT(reject()));
		
		 spinBox->setRange(tableWidget->MinY,tableWidget->MaxY);
	   spinBox->setValue(tableWidget->ActiveYear);
		 
		 connect(spinBox, SIGNAL(valueChanged(int)), tableWidget, SLOT(PlayYear(int)));
		
}
void SetData( QString d )
{
	data = d;
	tableWidget->Import(d);
	
}
void closeEvent( QCloseEvent * e )
{
 save();
}

    QGridLayout *gridLayout;
    Calendar *tableWidget;
    QHBoxLayout *hboxLayout;
    QLabel *label;
    QSpinBox *spinBox;
    QSpacerItem *spacerItem;
    QPushButton *pushButton;
    QPushButton *pushButton_2;
    QString data;

protected:
signals:
public slots:
void UpdateChoise(int ma,int mi ,int now )
{
	   setWindowTitle(tableWidget->windowTitle());
	   spinBox->setValue(now);
	   
}

void save()
{
	
	 data = tableWidget->Export();
	 accept();
}
  


};












   

















//
#endif // PREANNOSTRUCTURE_H

